<template>
    <div class="console-page search-page">
        <el-form inline :model="repositorySearchForm" class="e-page form-item forbid-select" spellcheck="false"
                 @submit.native.prevent @keyup.native.enter="searchInRepository">
            <el-row class="toolbar">
                <el-col :span="4" style="padding-right: 5px">
                    <el-input v-model="repositorySearchForm.q" placeholder="KeyWords" clearable
                              class="input-auto-resize"/>
                </el-col>
                <el-col :span="4" style="padding-right: 5px">
                    <el-input v-model="repositorySearchForm.group" placeholder="Group Id" clearable
                              class="input-auto-resize"/>
                </el-col>
                <el-col :span="4" style="padding-right: 5px">
                    <el-input v-model="repositorySearchForm.name" placeholder="Artifact Id" clearable
                              class="input-auto-resize"/>
                </el-col>
                <el-col :span="4" style="padding-right: 5px">
                    <el-input v-model="repositorySearchForm.version" placeholder="Version" clearable
                              class="input-auto-resize"/>
                </el-col>
                <el-col :span="4" style="padding-right: 5px">
                    <el-select v-model="repositorySearchForm.repository" class="input-auto-resize" clearable
                               popper-class="normal-poper" placeholder="Repository">
                        <el-option :label="item" :value="item"
                                   v-for="(item, index) in repositories.map(e => e.name).filter((item, index, array) => array.indexOf(item) === index)"
                                   :key="index"/>
                    </el-select>
                </el-col>
                <el-col :span="4" style="padding-right: 5px">
                    <el-icon @click="searchInRepository" class="button-auto-resize search-button cursor-pointer">
                        <Search/>
                    </el-icon>
                </el-col>
            </el-row>
        </el-form>
        <div class="repository-detail-header forbid-select no-wrap">
            <span class="repository-detail-title no-wrap" style="width: calc(calc(100% - 600px)*.4)">Artifact Id</span>
            <span class="repository-detail-title no-wrap" style="width: calc(calc(100% - 600px)*.6);">Group Id</span>
            <span class="repository-detail-title no-wrap" style="width: 200px;">Version</span>
            <span class="repository-detail-title no-wrap" style="width: 200px;">Repository</span>
            <span class="repository-detail-title no-wrap" style="width: 200px;">LastUpdated</span>
        </div>
        <div v-if="repositoryData.length === 0" class="no-data forbid-select">
            <div class="no-data-desc">暂无数据</div>
        </div>

        <el-scrollbar class="search-result" v-else ref="scrollbarRef">
            <div class="repository-detail-value-content" v-for="item in repositoryData">
                <div :class="`repository-detail-value forbid-select no-wrap c-${item.id}`" @click="showDetail(item)">
                    <span class="repository-detail-item " style="width: calc(calc(100% - 600px)*.4)">
                        <div class="no-wrap repository-detail-item-cell">
                            {{ item.name }}
                        </div>
                    </span>
                    <span class="repository-detail-item no-wrap" style="width: calc(calc(100% - 600px)*.6);">
                        <div class="no-wrap repository-detail-item-cell">
                            {{ item.group }}
                        </div>
                    </span>
                    <span class="repository-detail-item no-wrap" style="width: 200px;">
                        <div class="no-wrap repository-detail-item-cell">
                            {{ item.version }}
                        </div>
                    </span>
                    <span class="repository-detail-item no-wrap" style="width: 200px;">
                        <div class="no-wrap repository-detail-item-cell">
                            {{ item.repository }}
                        </div>
                    </span>
                    <span class="repository-detail-item no-wrap" style="width: 200px;">
                        <div class="no-wrap repository-detail-item-cell">
                            {{ item.lastUpdated }}
                        </div>
                    </span>
                </div>
                <div v-if="item.open" :class="`component-detail v-${item.id}`">
                    <el-table :data="item.assets" header-cell-class-name="el-table-header-cell"
                              cell-class-name="el-table-cell" class="forbid-select component-table">
                        <el-table-column label="name" prop="name" min-width="300">
                            <template #default="scope">
                                <div class="flex-display-center">
                                    <div @click="download(scope.row.checksum.sha1)" class="filename cursor-pointer">
                                        {{ scope.row.name }}
                                    </div>
                                </div>
                            </template>
                        </el-table-column>
                        <el-table-column label="contentType" prop="contentType" min-width="250"/>
                        <el-table-column label="fileSize" prop="fileSize" min-width="150">
                            <template #default="scope">
                                {{ formatSize(scope.row.fileSize) }}
                            </template>
                        </el-table-column>
                        <el-table-column label="extension" prop="maven2.extension" min-width="180">
                            <template #default="scope">
                                <span>{{ scope.row.maven2.extension }}</span>
                                <span v-if="scope.row.maven2.classifier"> ({{ scope.row.maven2.classifier }})</span>
                            </template>
                        </el-table-column>
                        <el-table-column label="lastModified" prop="lastModified" min-width="180">
                            <template #default="scope">
                                <span>{{ new Date(scope.row.lastModified).format("YYYY-MM-DD HH:mm:ss") }}</span>
                            </template>
                        </el-table-column>
                    </el-table>
                </div>
            </div>
        </el-scrollbar>
    </div>
</template>

<script setup>
import {useRequest, useElLoading, useElMessage} from "@usehook"
import {Search} from "@element-plus/icons-vue"
import {formatSize} from "@/utils/tools"
import {baseUrl} from "@/utils/constant"

let repositories = $ref([])
let repositoryData = $ref([])
let repositorySearchForm = $ref({
    sort: "",
    direction: "",
    q: "",
    repository: "",
    format: "",
    group: "",
    name: "",
    version: ""
})
let scrollbarRef = $ref(null)

const updateScrollbar = () => {
    // 更新scrollbar滚动条状态
    nextTick(() => scrollbarRef.update())
}

const showDetail = (item) => {
    // 先关闭其他所有的打开状态
    for (let i of repositoryData) {
        if (item.id === i.id) continue
        document.querySelector(".c-" + i.id).style.background = "none"
        if (i.open) {
            document.querySelector(".v-" + i.id).style.height = "0"
            updateScrollbar()
            // timeout写在每个对象上，避免单独维护
            clearTimeout(i.timeout)
            i.timeout = setTimeout(() => {
                i.open = false
                i.isOpen = false
                updateScrollbar()
            }, 500)
        }
    }
    //临时变量保存打开状态
    item.isOpen = !item.isOpen
    // 临时状态打开时更新open状态
    if (item.isOpen) {
        item.open = item.isOpen
        updateScrollbar()
    }
    // 调整高度和背景色
    nextTick(() => {
        if (item.open) document.querySelector(".v-" + item.id).style.height = item.isOpen ? "calc(55px *" + (item.assets.length + 1) + ")" : "0"
        updateScrollbar()
        document.querySelector(".c-" + item.id).style.background = item.isOpen ? "#ffb3b3" : "none"
    })
    clearTimeout(item.timeout)
    item.timeout = setTimeout(() => {
        item.open = item.isOpen
        updateScrollbar()
    }, 500)
}

const filterRepositorySearchForm = () => {
    return Object.fromEntries(
        Object.entries(repositorySearchForm).filter(([, value]) => {
            // 在这里添加你的非空检查逻辑
            return value !== null && value !== undefined && value !== ''
        })
    )
}

const searchInRepository = () => {
    const searchParams = filterRepositorySearchForm()
    if (Object.keys(searchParams).length === 0) {
        useElMessage.error({
            message: "请输入检索项进行文件搜索",
            clickClose: true,
            notice: true,
            offset: 0,
            position: "bottom-left"
        })
        return
    }
    const loading = useElLoading("正在加载仓库资源")
    useRequest("/mvn/repository/list", searchParams).then(resp => {
        if (resp && resp.status) {
            repositoryData = resp.data
            for (let item of resp.data) {
                item.lastUpdated = new Date(Math.max(...item.assets.map(e => new Date(e.lastModified).getTime()))).format('YYYY-MM-DD HH:mm:ss')
            }
        } else {
            useElMessage.error({message: resp.message || "文件搜索失败", clickClose: true, notice: true})
        }
    }).finally(() => loading.close())
}

const download = sha1 => {
    let link = document.createElement('a')
    link.target = "_blank"
    link.href = baseUrl + "/mvn/assets/download/" + sha1
    link.click()
    link.remove()
}

onMounted(() => {
    useRequest("/mvn/repositories", {}).then(resp => {
        if (resp && resp.status) {
            repositories = resp.data
        }
    })
})

</script>

<style>
.repository-detail .el-table__expanded-cell {
    background: transparent;
}

.repository-detail-title {
    display: inline-block;
    text-align: center;
}

.repository-detail-item {
    display: inline-block;
    text-align: center;
    height: 100%;
}

.repository-detail-item-cell {
    padding: 10px;
    height: 40px;
    line-height: 40px;
}

.repository-detail-header {
    height: 50px;
    line-height: 50px;
    font-size: 18px;
    background: rgba(185, 185, 185, .5);
    color: #909399;
}

.repository-detail-value {
    height: 60px;
    line-height: 60px;
    font-size: 16px;
    box-shadow: inset 0px -1px 0px 0px rgba(0, 0, 0, 0.1);
    transition: background .5s;
}

.repository-detail-value-content:hover {
    background: rgb(149 190 255 / .1);
}

.component-detail {
    will-change: height;
    transition: height .5s;
    height: 0;
    overflow: hidden;
    background: rgb(255 250 240 / 60%);
}

.confirm-title {
    width: 100px;
    display: inline-block;
    padding-right: 10px;
    text-align: right;
}

.confirm-item {
    display: inline-flex;
}

.confirm-line {
    height: 30px;
    line-height: 30px;
}

.confirm-value {
    width: 150px;
    display: inline-block;
    color: brown;
}

.search-button {
    font-size: 18px !important;
    background: rgb(64 158 255 / 80%);
    color: white;
    border-radius: 50%;
}

.search-button:hover {
    opacity: .7;
}

.search-page {
    padding: 0 5px;
    width: calc(100% - 10px);
}

.no-data {
    height: calc(100% - 95px);
    text-align: center;
    position: relative;
}

.no-data-desc {
    font-size: 18px;
    position: absolute;
    top: 30%;
    left: calc(50% - 36px);
}

.filename {
    width: fit-content;
    text-decoration-line: underline;
    color: blue
}

.search-result {
    height: calc(100% - 90px);
}

.search-result .el-scrollbar__thumb {
    transition: height .5s;
}

.component-table.el-table .el-table__cell {
    border: none !important;
}

.component-table.el-table .el-table__row,
.component-table.el-table .el-table__header {
    height: 55px !important;
}

.component-table.el-table .el-table__row {
    box-shadow: inset 0px 1px 0px 0px rgba(0, 0, 0, 0.1);
}
</style>